﻿//-----------------------------------------------------------------------
// <copyright file="LoginFailedException.cs" company="DylanBox">
// Copyright (c) DylanBox Corporation. All rights reserved.
// </copyright>
// <summary></summary>
// <reference>
//    http://blog.gurock.com/articles/creating-custom-exceptions-in-dotnet/
// </reference>
// <author>Dylan</author>
//-----------------------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization;

namespace SimpleSample
{



    /// <summary>
    ///  Let's see what FxCop says to our exception type
    ///     •Error for ImplementStandardExceptionConstructors:
    ///         Add the following constructor:
    ///         LoginFailedException(SerializationInfo, StreamingContext)
    ///     
    ///         This constructor is used to customize the serialization process of objects. 
    ///         And since the base Exception class defines such a constructor 
    ///         and C# still lacks the support of constructor inheritance, we are better off adding such a beast:
    ///     
    ///   ****C# lacks the support of constructor inheritance****    
    ///     
    ///     •Error for MarkISerializableTypesWithSerializable:
    ///         Add [Serializable] as this type implements ISerializable
    ///         
    ///         our base class Exception implements the ISerializable interface which is used to customize the serialization process, 
    ///         FxCop wonders why we didn’t add it. So, in order to comply with the serialization guidelines, we simply need to add the Serializable attribute and the second error is already fixed:
    /// </summary>
    [Serializable]
    public class LoginFailedException: System.Exception
    {

        public string LoginUserName
        {
            get;
            set;
        }            
            
        /// <summary>
        /// C# lacks the support of constructor inheritance, 
        /// this new type only has the standard constructor with no parameters and is therefore relatively useless. 
        /// so we have to defined explicitly since it would be gone otherwise. 
        /// </summary>
        public LoginFailedException()
        {
        }

        public LoginFailedException(string message)
            : base(message)
        {
        }

        public LoginFailedException(string message, Exception innerException)
            : base(message, innerException)
        {
        }

        /// <summary>
        /// enable deserialization feature
        /// We just restore our username field in the constructor with the aid of the previously filled SerializationInfo object. 
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        public LoginFailedException(SerializationInfo info, StreamingContext context)
            : base(info, context)
        {
            if (info != null)
            {
                this.LoginUserName = info.GetString("LoginUserName");
            }
        }

        /// <summary>
        /// enable serialization feature, Since our base Exception class already implements the ISerializable interface 
        /// we can omit it in the list of implemented interfaces and base classes, only need to override and fill the GetObjectData method. 
        /// </summary>
        /// <param name="info"></param>
        /// <param name="context"></param>
        public override void GetObjectData(SerializationInfo info, StreamingContext context)
        {
            // we call the GetObjectData method of the base class. 
            // This is needed to save the fields common to all exceptions, like the error message, stacktrace information or the inner exception.
            base.GetObjectData(info, context);

            // Then we simply store our username by adding it to the passed SerializationInfo object.
            if (info != null)
            {
                info.AddValue("LoginUserName", this.LoginUserName);
            }
        }
    }
}
